package com.euvmp.sdk;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;

import java.util.Objects;

/**
 * @Description 实际用于处理sdk相关事务的单元
 * @Author YangZheng 328170112@qq.com
 * @Date 2020-06-30 11:44
 */
public class SDKUnit {
    private final long   timeDiff;
    private final String appId;
    private final String appKey;
    private final String url;
    private final EncryptionHelper encryption;

    private static SDKUnit currentOne;

    public static SDKUnit getIntance(String appId, String appKey, String url){
        if(currentOne == null || !currentOne.appId.equals(appId) || !currentOne.appKey.equals(appKey) || !currentOne.url.equals(url)) {
            synchronized (SDKUnit.class) {
                if(currentOne == null || !currentOne.appId.equals(appId) || !currentOne.appKey.equals(appKey) || !currentOne.url.equals(url)) {
                    currentOne = new SDKUnit(appId, appKey, url);
                }
            }
        }
        return currentOne;
    }

    private SDKUnit(String appId, String appKey, String url) {
        verify(appId, "appId不能为空");
        verify(appKey, "appKey不能为空");
        verify(url, "请求地址URL不能为空");
        this.url = url;
        String time = getSystemTime();
        verify(time, "时间校验失败");

        this.appId = appId;
        this.appKey = appKey;
        this.timeDiff = Long.parseLong(time) - System.currentTimeMillis();
        this.encryption = new EncryptionHelper(appKey);
    }

    public String send(String sid, String content, int timeout) {
        verify(sid, "sid不能为空");
        verify(content, "content不能为空");
        long time = System.currentTimeMillis() + timeDiff;
        content = encryption.encode(content);
        String body = HttpRequest.post(url)
                                 .timeout(timeout)
                                 .form("z", sid)
                                 .form("i", appId)
                                 .form("t", time)
                                 .form("c", content)
                                 .form("s", sign(sid,time,content))
                                 .execute()
                                 .body();
        return encryption.decode(body);
    }

    private String sign(String sid,long time,String content){
        StringBuffer signStr = new StringBuffer();
        signStr.append("z=").append(sid)
               .append("&i=").append(appId)
               .append("&t=").append(time)
               .append("&k=").append(appKey)
               .append("&c=").append(content);
        return SecureUtil.sha1(signStr.toString());
    }

    private String getSystemTime() {
        return HttpUtil.get(url+"/time");
    }

    private void verify(String v, String msg) {
        if (v == null || v.trim().length() == 0) {
            throw new YptException(msg);
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SDKUnit unit = (SDKUnit) o;
        return Objects.equals(appId, unit.appId) && Objects.equals(appKey, unit.appKey) && Objects.equals(url, unit.url);
    }

    @Override
    public int hashCode() {
        return Objects.hash(appId, appKey, url);
    }
}
